package edu.boun.g4.coursity.service;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import edu.boun.g4.coursity.domain.Course;
import edu.boun.g4.coursity.domain.SemanticTag;

/**
 * @author mertusta
 * @author alifindik
 * 
 */
@Service("semanticTagService")
@Transactional
public class SemanticTagService {

	protected static Logger logger = Logger.getLogger("service");

	@Resource(name = "sessionFactory")
	private SessionFactory sessionFactory;

	/**
	 * Retrieves all semanticTags
	 * 
	 * @return a list of semanticTags
	 */
	@SuppressWarnings("unchecked")
	public List<SemanticTag> getAll() {
		logger.debug("Retrieving all semanticTags");

		// Retrieve session from Hibernate
		Session session = sessionFactory.getCurrentSession();

		// Create a Hibernate query (HQL)
		Query query = session.createQuery("FROM SemanticTag");

		// Retrieve all
		return query.list();
	}

	// /**
	// * Retrieves semantic tags of a course
	// */
	// public List<SemanticTag> getAllBackground(Integer courseId) {
	// logger.debug("Retrieving semantic tags of the course for recommended background");
	//
	// // Retrieve session from Hibernate
	// Session session = sessionFactory.getCurrentSession();
	//
	// // Create a Hibernate query (HQL)
	// Query query = session
	// .createQuery("FROM Course as p LEFT JOIN FETCH  p.recommendedBackground WHERE p.id="
	// + courseId);
	//
	// Course course = (Course) query.uniqueResult();
	//
	// // Retrieve all
	// return new ArrayList<SemanticTag>(course.getRecommendedBackground());
	// }

	/**
	 * Retrieves semantic tags of a course
	 */
	public List<SemanticTag> getAllCategories(Integer courseId) {
		logger.debug("Retrieving semantic tags of the course for categories");

		// Retrieve session from Hibernate
		Session session = sessionFactory.getCurrentSession();

		// Create a Hibernate query (HQL)
		Query query = session
				.createQuery("FROM Course as p LEFT JOIN FETCH  p.categories WHERE p.id="
						+ courseId);

		Course course = (Course) query.uniqueResult();

		// Retrieve all
		return new ArrayList<SemanticTag>(course.getCategories());
	}

	/**
	 * Retrieves a single semanticTag
	 */
	public SemanticTag get(Integer id) {
		// Retrieve session from Hibernate
		Session session = sessionFactory.getCurrentSession();

		// Retrieve existing semanticTag first
		SemanticTag semanticTag = (SemanticTag) session.get(SemanticTag.class,
				id);

		return semanticTag;
	}

	/**
	 * Adds a new semanticTag
	 */
	public void add(Integer courseId, SemanticTag semanticTag) {
		logger.debug("Adding new semanticTag");

		// Retrieve session from Hibernate
		Session session = sessionFactory.getCurrentSession();

		// Persists to db
		session.save(semanticTag);

		// Add to course as well
		// Retrieve existing course via id
		Course existingCourse = (Course) session.get(Course.class, courseId);

		// Assign updated values to this course
		existingCourse.getCategories().add(semanticTag);

		// Save updates
		session.save(existingCourse);

	}

	/**
	 * Deletes an existing semanticTag
	 * 
	 * @param id
	 *            the id of the existing semanticTag
	 */
	public void delete(Integer id) {
		logger.debug("Deleting existing semanticTag");

		// Retrieve session from Hibernate
		Session session = sessionFactory.getCurrentSession();

		// Retrieve existing semanticTag first
		SemanticTag semanticTag = (SemanticTag) session.get(SemanticTag.class,
				id);

		// Delete
		session.delete(semanticTag);
	}

	/**
	 * Edits an existing initiative
	 */
	public void edit(SemanticTag semanticTag) {
		logger.debug("Editing existing semanticTag");

		// Retrieve session from Hibernate
		Session session = sessionFactory.getCurrentSession();

		// Retrieve existing semanticTag via id
		SemanticTag existingSemanticTag = (SemanticTag) session.get(
				SemanticTag.class, semanticTag.getId());

		// Assign updated values to this semanticTag
		existingSemanticTag.setTagName((semanticTag.getTagName()));

		// Save updates
		session.save(existingSemanticTag);
	}
}
